Prolog
概述
Prolog 是基于谓词逻辑的理论. 最基本的写法是定立物件与物件之间的关系, 之后可以用询问目标的方式来查询各种物件之间的关系, 系统会自动进行匹配及回溯, 找出所询问的答案. 目前 Prolog 主要用在人工智能和计算机语言的研究领域.
得益于 Prolog 的模式匹配功能, Prolog 非常适合快速的开发一个语言的解析器, 所以很多计算机科学家在开发新的程序语言时, 喜欢用 Prolog 先写一个实现, 然后观察大众的反应, 如何大众认为这个语言很好, 就用更快的语言如 C++ 来重新写解释器, 如果大众的反应不好, 就再用Prolog进行修改.
基本使用
swipl # 进入 Prolog 环境 writenln('Hello World'). # 输出 Hello World true # 退出 halt.
输出 true 的原因:
整个过程中 Prolog 都在试图证明这个语句是真是假, 向屏幕输出 "Hello World" 这件事实际上是执行这个语句的"副作用"(side effect)! 在 Prolog 中, 很多任务都是靠副作用来实现的, 包括输入输出, 甚至是参数的传递.
语法
考虑以下代码:
male(di). male(jianbo). female(xin). female(yuan). female(yuqing). father(jianbo,di). father(di,yuqing). mother(xin,di). mother(yuan,yuqing). grandfather(X,Y):-father(X,Z),father(Z,Y). grandmother(X,Y):-mother(X,Z),father(Z,Y). daughter(X,Y):-father(X,Y),female(Y).
保存为 xxx.pl, 进入 Prolog 环境执行: consult('path/to/xxx.pl').
- 子句: 代码里面的每一行都是一个
子句
(clause) - :- 子句:
规则
- 不带 :- 子句:
事实
- di, jianbo 这类以小写英文字母开头的名称:
原子
, 原子的值不可变 - X, Y 这类以大写英文字母开头的名称:
变量
- , : 且
- ; : 或
查询
grandfather(X,yuqing). # 输出 X = jianho.
grandfather(X,Y):-father(X,Z),father(Z,Y). 的意思: X 是 Z 的父亲并且 Z 是 Y 的父亲时, X 是 Y 的祖父.
回溯规则
parent(keyuan,jianbo). parent(jianbo,di). parent(di,yuqing). ancestor(X,Y):-parent(X,Y). ancestor(X,Y):-parent(X,Z),ancestor(Z,Y).
规则可以这样解读: X 是 Y 的祖先基于两个条件: X 是 Y 的 parent; 或者存在一个 Z, 使得 X 是 Z 的 parent 并且 Z 是 Y 的祖先.
Prolog 查询的原理
仍以上面的 ancestor 为例. 当我们询问 ancestor(keyuan,yuqing). 时, Prolog 会试图证明这个查询.
查找 ancestor 的定义:
关于 ancestor 有两条定义, 首先使用第一条规则, 将两个变量用原子代入: ancestor(keyuan,yuqing) = ancestor(X, Y), 返回 false.
于是使用第二条规则. 变成: parent(keyuan, Z),ancestor(Z,yuqing). Prolog 依次证明这两条规则是否为 true.
最终证明过程如下图所示:
Prolog 是用深度优先(depth-first search)的算法来寻找答案的. 当一个规则或者是事实不符合时, Prolog 会通过回溯的方式回到之前的状态, 然后去尝试另外的规则或者是事实, 知道你的查询(query)被证明为止. 如果所有的可能性都搜索过了, 你的查询仍然不能得到证实, 那么 Prolog 会认为你的查询证实不了, 返回 "false".
Generated by Emacs 25.x(Org mode 8.x)
Copyright © 2014 - Pinvon - Powered by EGO